package acs.http;

import static io.netty.buffer.Unpooled.copiedBuffer;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import acs.offer.collection.Params;
import acs.offer.constant.Constant;
import acs.offer.constant.EventType;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.MemoryAttribute;

@Sharable
public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
	private static Map<String, Channel> channelMap = new HashMap<>();

	
	
	public HttpServerHandler() {
		System.out.println("HttpServerHandler 调用了....");
	}

	int count=0;
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
		System.out.println("收到请求uri：" + req.uri());
		System.out.println("count：" + ++count);
		Params params = Params.build().put(Constant.REQUEST_URI, req.uri());
		Map<String, Object> reqParam;
		if (req.method() == HttpMethod.POST) {
			reqParam = this.getPostParamsFromChannel(req);
		} else {
			reqParam = this.getGetParamsFromChannel(req);
		}
		params.put(Constant.REQUEST_TYPE, this.getRequestType(req.uri()));
		params.put(Constant.REQUEST_PARAMS, reqParam);
		String sessionId = UUID.randomUUID().toString();
		params.put(Constant.SESSION_ID, sessionId);

		EventBus.getInstance().putMessage(EventType.CLICK_REQUEST, params);
		channelMap.put(sessionId, ctx.channel());
	}

	/**
	 * 在获取数据超时时移除客户端channel
	 * 
	 * @param params
	 */
	public static void removeChannel(Params params) {
		String sessionId = params.get(Constant.SESSION_ID);
		Channel channel = channelMap.remove(sessionId);
		if (channel == null) {
			return;
		}
		if (params.get(Constant.RESPONSE_DATA) == null) {
			channel.writeAndFlush(responseOK(HttpResponseStatus.OK, "我是默认数据啦，服务端获取不到你想要的数据"))
					.addListener(ChannelFutureListener.CLOSE);
		}
	}

	public static void sendMessage(Params params) {
		Map<String, String> content = params.get(Constant.RESPONSE_DATA);
		String sessionId = params.get(Constant.SESSION_ID);
		Channel channel = channelMap.remove(sessionId);
		if (channel == null) {
			return;
		}
		ByteBuf byteBuf = copiedBuffer(content.toString().getBytes());
		FullHttpResponse response = responseOK(HttpResponseStatus.OK, byteBuf);
		channel.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	}

	private static FullHttpResponse responseOK(HttpResponseStatus status, String content) {
		ByteBuf byteBuf = copiedBuffer(content.toString().getBytes());
		return responseOK(status, byteBuf);
	}

	private static FullHttpResponse responseOK(HttpResponseStatus status, ByteBuf content) {
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, content);
		if (content != null) {
			response.headers().set("Content-Type", "text/plain;charset=UTF-8");
			response.headers().set("Content_Length", response.content().readableBytes());
		}
		return response;
	}

	private String getRequestType(String uri) {
		int i = uri.indexOf("?");
		if (i == -1) {
			throw new RuntimeException("url 非法");
		}
		return uri.substring(1, i);
	}

	/**
	 * 请求参数转map
	 * 
	 * @param uri
	 * @return
	 */
	private Map<String, String> requestParamToMap(String uri) {
		Map<String, String> result = new HashMap<String, String>();
		String params = uri.substring(uri.indexOf("?") + 1);
		String[] split = params.split("&");
		for (int i = 0; i < split.length; i++) {
			String[] param = split[i].split("=");
			result.put(param[0], param[1]);
		}
		return result;
	}

	/*
	 * 获取GET方式传递的参数
	 */
	private Map<String, Object> getGetParamsFromChannel(FullHttpRequest fullHttpRequest) {
		Map<String, Object> params = new HashMap<String, Object>();
		if (fullHttpRequest.method() == HttpMethod.GET) {
			// 处理get请求
			QueryStringDecoder decoder = new QueryStringDecoder(fullHttpRequest.uri());
			Map<String, List<String>> paramList = decoder.parameters();
			for (Map.Entry<String, List<String>> entry : paramList.entrySet()) {
				params.put(entry.getKey(), entry.getValue().get(0));
			}
			return params;
		} else {
			return null;
		}

	}

	/*
	 * 获取POST方式传递的参数
	 */
	private Map<String, Object> getPostParamsFromChannel(FullHttpRequest fullHttpRequest) {

		Map<String, Object> params = new HashMap<String, Object>();

		if (fullHttpRequest.method() == HttpMethod.POST) {
			// 处理POST请求
			String strContentType = fullHttpRequest.headers().get("Content-Type").trim();
			if (strContentType.contains("x-www-form-urlencoded")) {
				params = getFormParams(fullHttpRequest);
			} else if (strContentType.contains("application/json")) {
				try {
					params = getJSONParams(fullHttpRequest);
				} catch (UnsupportedEncodingException e) {
					return null;
				}
			} else {
				return null;
			}
			return params;
		} else {
			return null;
		}
	}

	/*
	 * 解析json数据（Content-Type = application/json）
	 */
	private Map<String, Object> getJSONParams(FullHttpRequest fullHttpRequest) throws UnsupportedEncodingException {
		Map<String, Object> params = new HashMap<String, Object>();

		ByteBuf content = fullHttpRequest.content();
		byte[] reqContent = new byte[content.readableBytes()];
		content.readBytes(reqContent);
		String strContent = new String(reqContent, "UTF-8");

		return params;
	}

	/*
	 * 解析from表单数据（Content-Type = x-www-form-urlencoded）
	 */
	private Map<String, Object> getFormParams(FullHttpRequest fullHttpRequest) {
		Map<String, Object> params = new HashMap<String, Object>();

		HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), fullHttpRequest);
		List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();

		for (InterfaceHttpData data : postData) {
			if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
				MemoryAttribute attribute = (MemoryAttribute) data;
				params.put(attribute.getName(), attribute.getValue());
			}
		}

		return params;
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		String ip = ctx.channel().remoteAddress().toString();
		if (ip != null) {
			if (ip.contains("/")) {
				ip = ip.substring(ip.indexOf("/") + 1);
			}
			if (ip.contains(":")) {
				ip = ip.substring(0, ip.indexOf(":"));
			}
		}
		System.out.println("ip="+ip);
	}
	
}